/**
 * Created by IntelliJ IDEA.
 * User: wangyongchao
 * Date: 2018/7/30
 * Time: 11:43
 */

//name(字母、数字、下划线、中划线、中文组成且32位)
export function checkNameCH(isNameCH) {
  var rg = /^[\u4e00-\u9fa5|a-zA-Z0-9|_|\-\.]{0,31}$/;
  var exceptStr = "NMC_";	//名字不能以此开头
  var exceptStr1 = "hub";	//名字不能以此开头
  if (isNameCH.length == 0 || isNameCH == "") {
    return;
  }
  if (isNameCH != "" &&
      (!rg.test(isNameCH) ||
        (isNameCH.indexOf(exceptStr) == 0) ||
        (isNameCH.indexOf(exceptStr1) == 0) ||
        isNameCH.replace(/[\u4e00-\u9fa5]/ig, 'xxx').length > 32)) {
    return false;
  }
  return true;
}

/**
 * 校验IP
 * @param ip
 * @returns {boolean}
 */
export function checkIpUtil(ip) {
  var rg = /^(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)$/;
  return rg.test(ip);
}

//检查textarea里的ip
export function checkIpsUtil(ips) {
  var ipArr = [];	//检查IP
  var ipArr2 = [];
  var subArr = [];		//检查掩码

  var rg = /^(((\d{1})|(\d{2})|(1\d{2})|(2[0-4]\d{1})|(25[0-5]))\.){3}((\d{1})|(\d{2})|(1\d{2})|(2[0-4]\d{1})|(25[0-5]))$/;

  var rg2 = /^(254|252|248|240|224|192|128|0)\.0\.0\.0|255\.(254|252|248|240|224|192|128|0)\.0\.0|255\.255\.(254|252|248|240|224|192|128|0)\.0|255\.255\.255\.(255|254|252|248|240|224|192|128|0)$/;
  var rg3 = /^([0-9]|1[0-9]|2[0-9]|3[0-2])$/;

  var str1 = "All";
  var str2 = "全部";

  /*判断IP是否合法*/
  if (ips.length == 0) {
    return false;
  }

  if (str1 == ips || str2 == ips) {
    ;
  } else {
    ipArr = ips.split(/\n/g);   //查找每一个textarea里的ip总个数，以回车符分割;ipArr[i]为总行数组

    for (var j = 0; j < ipArr.length; j++)	//查找出的每一个IP判断是否带有掩码，若有则提取出IP
    {
      //----该if语句是用来判断是否为IE浏览器，是的话，则少取一个字符（IE6/7/8取字符与IE9/10/11及FF不同）
      if ((navigator.appName.indexOf("Microsoft") != -1) && (!-[1,]) && (j < ipArr.length - 1)) {

        ipArr[j] = ipArr[j].substring(0, ipArr[j].length - 1);
      }
      ipArr[j] = ipArr[j].replace(/(^\s*)|(\s*$)/g, "");	//去除字符串空格
      if (ipArr[j].search(/\//g) != -1)		//若不等于-1，说明该IP带有掩码,提取IP  ipArr[j]为每行ip数组（含掩码）
      {
        subArr.push(ipArr[j].substring(ipArr[j].search(/\//g) + 1));	//提取掩码
        ipArr[j] = ipArr[j].substring(0, ipArr[j].search(/\//g));		//提取含掩码的ip

        //subArr[j]=ipArr[j].substring(ipArr[j].search(/\//g)+1));
      } else if (ipArr[j].search(/\-/g) != -1) {
        ipArr2.push(ipArr[j].substring(ipArr[j].search(/\-/g) + 1));
        ipArr[j] = ipArr[j].substring(0, ipArr[j].search(/\-/g));
      }

      if (ips != "" && !rg.test(ipArr[j])) {
        return false;

      } else if (ips && ipArr2[j] != null) {
        for (var k = 0; k < ipArr2.length; k++) {
          if (!(rg.test(ipArr2[k]))) {
            return false;
          }
        }
      } else if (ips != '') {
        for (var k = 0; k < subArr.length; k++) {
          if (!(rg2.test(subArr[k]) || rg3.test(subArr[k]))) {
            return false;
          }
        }
      }
    }
  }

  return true;
}

/**
 * 根据起止IP，获取要被创建的节点data
 * @param firstIp
 * @param lastIp
 * @returns {Array} {label:'名称', firstIp:起IP, lastIp:止IP, directShow:是否直接显示}
 */
export function getCreateData(firstIp, lastIp) {
  var fIpList = firstIp.split('.');
  var lIpList = lastIp.split('.');

  if ((lIpList[0] - fIpList[0]) > 0) {
    //止IP的第一位比起IP的第一位大
    //因生产数据为  192.168.0.0/8   的显示名称类数据
    return createAClassNetData(parseInt(fIpList[0]),
      parseInt(lIpList[0]), firstIp, lastIp);
  }

  if ((lIpList[1] - fIpList[1]) > 0) {
    //止IP的第二位比起IP的第二位大
    //因生产数据为  192.168.0.0/16   的显示名称类数据
    return createBClassNetData(fIpList[0],
      parseInt(fIpList[1]), parseInt(lIpList[1]),
      firstIp, lastIp);
  }

  if ((lIpList[2] - fIpList[2]) > 0) {
    //止IP的第三位比起IP的第三位大
    //因生产数据为  192.168.0.0/24   的显示名称类数据
    return createCClassNetData(fIpList[0] + '.' + fIpList[1],
      parseInt(fIpList[2]), parseInt(lIpList[2]),
      firstIp, lastIp);
  }

  if ((lIpList[3] - fIpList[3]) >= 0) {
    //止IP的第四位比起IP的第四位大
    //因生产数据为  192.168.0.0/24   的显示名称类数据
    return createOneCClassNetData(fIpList[0] + '.' + fIpList[1] + '.' + fIpList[2],
      firstIp, lastIp);
  }
}

//创建一个C类网络数据
export function createOneCClassNetData(header, firstIp, lastIp) {
  var dataList = [{
    'label': header + '.0/24',
    'firstIp': firstIp,
    'lastIp': lastIp,
    'directShow': true
  }];

  return dataList;
}

//创建C类网络数据
export function createCClassNetData(header, stratNum, endNum, firstIp, lastIp) {
  var dataList = [];
  var createDataFirst = true;
  for (var i = stratNum; i <= endNum; i++) {
    dataList.push({
      'label': header + '.' + i + '.0/24',
      'firstIp': createDataFirst ? firstIp : header + '.' + i + '.0',
      'lastIp': i === endNum ? lastIp : header + '.' + i + '.255',
      'directShow': true
    });

    createDataFirst = false;
  }

  return dataList;
}

//创建B类网络数据
export function createBClassNetData(header, stratNum, endNum, firstIp, lastIp) {
  var dataList = [];
  var createDataFirst = true;
  for (var i = stratNum; i <= endNum; i++) {
    dataList.push({
      'label': header + '.' + i + '.0.0/16',
      'firstIp': createDataFirst ? firstIp : header + '.' + i + '.0.0',
      'lastIp': i === endNum ? lastIp : header + '.' + i + '.255.255',
      'directShow': false
    });

    createDataFirst = false;
  }

  return dataList;
}

//创建A类网络数据
export function createAClassNetData(stratNum, endNum, firstIp, lastIp) {
  var dataList = [];
  var createDataFirst = true;
  for (var i = stratNum; i <= endNum; i++) {
    dataList.push({
      'label': i + '.0.0.0/8',
      'firstIp': createDataFirst ? firstIp : i + '.0.0.0',
      'lastIp': i === endNum ? lastIp : i + '.255.255.255',
      'directShow': false
    });

    createDataFirst = false;
  }

  return dataList;
}


/**
 * 根据输入的IP+掩码，或IP地址段，获取起止IP地址段数组
 * @param str
 * @returns {Array}
 */
export function getStartAndEndIpList(str) {
  var ipList = [];
  if (str === '') {
    ipList.push('0.0.0.0-255.255.255.255');
    return ipList;
  }


  if (str.indexOf('\n') > 0) {
    ipList = str.split('\n');

    for (var i = 0; i < ipList.length; i++) {
      ipList[i] = ipList[i].replace('<br>', '');
    }
  } else if (str.indexOf('<br>') > 0) {
    ipList = str.split('<br>');
  } else {
    ipList.push(str);
  }

  for (var i = 0; i < ipList.length; i++) {
    ipList[i] = getStartAndEndIp(ipList[i]);
  }

  return ipList;
}

/**
 * 根据输入的IP+掩码，或IP地址段，获取起止IP地址段
 * @param str
 * @returns {*}
 */
export function getStartAndEndIp(str) {
  //如果是IP地址段，就直接返回
  if (str.indexOf('-') > 0) {
    return str;
  }

  var ip = str;
  var maskLong = 0;
  var mask = 0;

  //判断是否存在掩码，存在掩码的需要处理掩码
  // 不存在掩码的，将IP变成IP-IP的形式，返回
  if (ip.indexOf('/') > 0) {
    mask = ip.substring(ip.indexOf('/') + 1);
    ip = ip.substring(0, ip.indexOf('/'));
  } else {
    ip = ip + '-' + ip;

    return ip;
  }

  //对于存在掩码的，如果掩码是数字，就赋值给maskLong
  //不是数字，就要计算出数字
  var reg = /^[0-9]+.?[0-9]*$/;
  if (!reg.test(mask)) {
    maskLong = computeSNMA(mask);
  } else {
    maskLong = mask;
  }

  return computeIp(ip, maskLong);
}

/***
 * 计算IP地址段
 * @param ip
 * @param mask
 * @returns {number}
 */
export function computeIp(ip, mask) {
  var ipList = ip.split('.');
  //将掩码（24格式）转为掩码（255.255.255.255格式）
  var rt = calcNWmask(mask);
  //网关
  var ipNw = [];
  //第一个可用IP
  var ipFirst = [];
  //最后一个可用IP
  var ipLast = [];
  //广播地址
  var ipBcast = [];

  if (mask == 31) {
    ipFirst[0] = ipList[0] & rt[0]
    ipFirst[1] = ipList[1] & rt[1]
    ipFirst[2] = ipList[2] & rt[2]
    ipFirst[3] = ipList[3] & rt[3]
    //
    ipLast[0] = ipList[0] | (~rt[0] & 0xff);
    ipLast[1] = ipList[1] | (~rt[1] & 0xff);
    ipLast[2] = ipList[2] | (~rt[2] & 0xff);
    ipLast[3] = ipList[3] | (~rt[3] & 0xff);
    return ipList.join('.') + '-' + ipLast.join('.');
  }
  if (mask == 32) {
    ipFirst[0] = ipList[0];
    ipFirst[1] = ipList[1];
    ipFirst[2] = ipList[2];
    ipFirst[3] = ipList[3];
    return ipList.join('.') + '-' + ipList.join('.');
  }
  var canUserIpCount = Math.pow(2, 32 - mask) - 2;
  //
  ipBcast[0] = ipList[0] | (~rt[0] & 0xff);
  ipBcast[1] = ipList[1] | (~rt[1] & 0xff);
  ipBcast[2] = ipList[2] | (~rt[2] & 0xff);
  ipBcast[3] = ipList[3] | (~rt[3] & 0xff);
  //
  ipNw[0] = ipList[0] & rt[0]
  ipNw[1] = ipList[1] & rt[1]
  ipNw[2] = ipList[2] & rt[2]
  ipNw[3] = ipList[3] & rt[3]
  //
  ipFirst[0] = ipNw[0];
  ipFirst[1] = ipNw[1];
  ipFirst[2] = ipNw[2];
  ipFirst[3] = ipNw[3] + 1;
  //
  ipLast[0] = ipBcast[0];
  ipLast[1] = ipBcast[1];
  ipLast[2] = ipBcast[2];
  ipLast[3] = ipBcast[3] - 1;

  return ipNw.join('.') + '-' + ipBcast.join('.');
}

/***
 * 根据255.255.255.255格式的掩码，计算数字掩码
 * @param mask
 * @returns {*|number}
 */
export function computeSNMA(mask) {
  var maskArray = mask.split('.');

  maskArray[0] = snmcorrect(maskArray[0]);
  if (maskArray[0] < 255) {
    maskArray[1] = 0;
    maskArray[2] = 0;
    maskArray[3] = 0;
  } else {
    maskArray[1] = snmcorrect(maskArray[1]);
    if (maskArray[1] < 255) {
      maskArray[0] = 255;
      maskArray[2] = 0;
      maskArray[3] = 0;
    } else {
      maskArray[2] = snmcorrect(maskArray[2]);
      if (maskArray[2] < 255) {
        maskArray[0] = 255;
        maskArray[1] = 255;
        maskArray[3] = 0;
      } else {
        maskArray[3] = snmcorrect(maskArray[3]);
      }
    }
  }
  var bits = 0;
  bits = bits + d2bits(maskArray[0]);
  bits = bits + d2bits(maskArray[1]);
  bits = bits + d2bits(maskArray[2]);
  bits = bits + d2bits(maskArray[3]);

  return bits;
}

export function snmcorrect(decimal) {
  var snmcorr = decimal;
  if (decimal > 255) snmcorr = 255;
  if (decimal == 253) snmcorr = 254;
  if ((decimal > 248) && (decimal < 252)) snmcorr = 252;
  if ((decimal > 240) && (decimal < 248)) snmcorr = 248;
  if ((decimal > 224) && (decimal < 240)) snmcorr = 240;
  if ((decimal > 192) && (decimal < 224)) snmcorr = 224;
  if ((decimal > 128) && (decimal < 192)) snmcorr = 192;
  if ((decimal > 0) && (decimal < 128)) snmcorr = 128;
  if (decimal < 0) snmcorr = 0;
  return (snmcorr);
}

export function d2bits(decimal) {
  var bits = 0;
  if (decimal & 128) {
    bits = bits + 1
  }
  if (decimal & 64) {
    bits = bits + 1
  }
  if (decimal & 32) {
    bits = bits + 1
  }
  if (decimal & 16) {
    bits = bits + 1
  }
  if (decimal & 8) {
    bits = bits + 1
  }
  if (decimal & 4) {
    bits = bits + 1
  }
  if (decimal & 2) {
    bits = bits + 1
  }
  if (decimal & 1) {
    bits = bits + 1
  }
  return (bits);
}

/**
 * 将掩码（24格式）转为掩码（255.255.255.255格式）
 * @param bits
 * @returns {number[]}
 */
export function calcNWmask(bits) {
  var temp = [0, 0, 0, 0];

  temp[0] = 0;
  temp[1] = 0;
  temp[2] = 0;
  temp[3] = 0;
  if (bits >= 8) {
    temp[0] = 255;
    bits -= 8;
  } else {
    temp[0] = h_fillbitsfromleft(bits);
    return temp;
  }
  if (bits >= 8) {
    temp[1] = 255;
    bits -= 8;
  } else {
    temp[1] = h_fillbitsfromleft(bits);
    return temp;
  }
  if (bits >= 8) {
    temp[2] = 255;
    bits -= 8;
  } else {
    temp[2] = h_fillbitsfromleft(bits);
    return temp;
  }
  temp[3] = h_fillbitsfromleft(bits);
  return temp;
}

export function h_fillbitsfromleft(num) {
  if (num >= 8) {
    return (255);
  }
  var bitpat = 0xff00;
  while (num > 0) {
    bitpat = bitpat >> 1;
    num--;
  }
  return (bitpat & 0xff);
}

export function ipToNumber(ip) {
  var num = 0;
  try {
    if(ip == "" || !ip) {
      return num;
    }
    var aNum = ip.split(".");
    if(aNum.length != 4) {
      return num;
    }
    num += parseInt(aNum[0]) << 24;
    num += parseInt(aNum[1]) << 16;
    num += parseInt(aNum[2]) << 8;
    num += parseInt(aNum[3]) << 0;
    num = num >>> 0;//这个很关键，不然可能会出现负数的情况
  } catch (e) {
    num = 0;
  }
  return num;
}

export function numberToIp(number) {
  var ip = "";
  if(number <= 0) {
    return ip;
  }
  var ip3 = (number << 0 ) >>> 24;
  var ip2 = (number << 8 ) >>> 24;
  var ip1 = (number << 16) >>> 24;
  var ip0 = (number << 24) >>> 24

  ip += ip3 + "." + ip2 + "." + ip1 + "." + ip0;

  return ip;
}
